﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Input;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Data;

namespace GeoStructor
{
    public class TemplatedSelectionAdorner : Adorner
    {
        // Be sure to call the base class constructor.
        public TemplatedSelectionAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            this.DataContext = this;
            _children = new VisualCollection(this);
            Cursor = Cursors.Cross;
            _content = new ContentControl
            {
                Content = new ContentPresenter()
            };
            _children.Add(_content);
            AddLogicalChild(_content);
            _content.SetBinding(ContentControl.ContentTemplateProperty, new Binding
            {
                Source = AdornedElement,
                Path = new PropertyPath(AdornerContentTemplateProperty)
            });
        }

        private bool mouseuponce = false;

        protected override void OnMouseMove(MouseEventArgs e)
        {
            if (!mouseuponce)
            {
                var pos = e.GetPosition(this.AdornedElement);
                if (pos.X < 0) pos.X = 0;
                if (pos.Y < 0) pos.Y = 0;
                if (pos.X > this.AdornedElement.RenderSize.Width) pos.X = this.AdornedElement.RenderSize.Width;
                if (pos.Y > this.AdornedElement.RenderSize.Height) pos.Y = this.AdornedElement.RenderSize.Height;
                Finish = pos;
                
            }
            base.OnMouseMove(e);
        }

        protected override void OnMouseUp(MouseButtonEventArgs e)
        {
            mouseuponce = true;
            ReleaseMouseCapture();
            base.OnMouseUp(e);
        }

        private VisualCollection _children;
        private ContentControl _content;

        protected override int VisualChildrenCount
        {
            get
            {
                return _children.Count;
            }
        }

        protected override Size MeasureOverride(Size constraint)
        {
            _content.Measure(constraint);
            return _content.DesiredSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _content.Arrange(new Rect(finalSize));
            return finalSize;
        }

        protected override Visual GetVisualChild(int index)
        {
            return _children[index];
        }

        protected override System.Collections.IEnumerator LogicalChildren
        {
            get
            {
                var list = new List<UIElement>();
                list.Add(_content);
                return (System.Collections.IEnumerator)list.GetEnumerator();
            }
        }

        public static DataTemplate GetAdornerContentTemplate(DependencyObject obj)
        {
            return (DataTemplate)obj.GetValue(AdornerContentTemplateProperty);
        }

        public static void SetAdornerContentTemplate(DependencyObject obj, DataTemplate value)
        {
            obj.SetValue(AdornerContentTemplateProperty, value);
        }

        // Using a DependencyProperty as the backing store for AdornerContentTemplate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AdornerContentTemplateProperty =
            DependencyProperty.RegisterAttached("AdornerContentTemplate", typeof(DataTemplate), typeof(TemplatedSelectionAdorner), new UIPropertyMetadata(null));

        public Rect Rect
        {
            get { return (Rect)GetValue(RectProperty); }
            set { SetValue(RectProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Rect.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RectProperty =
            DependencyProperty.Register("Rect", typeof(Rect), typeof(TemplatedSelectionAdorner), new UIPropertyMetadata(null));

        public Point Start
        {
            get { return (Point)GetValue(StartProperty); }
            set { SetValue(StartProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Start.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StartProperty =
            DependencyProperty.Register("Start", typeof(Point), typeof(TemplatedSelectionAdorner), new UIPropertyMetadata(default(Point), VisualPropertyChanged));

        public Point Finish
        {
            get { return (Point)GetValue(FinishProperty); }
            set { SetValue(FinishProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Finish.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FinishProperty =
            DependencyProperty.Register("Finish", typeof(Point), typeof(TemplatedSelectionAdorner), new UIPropertyMetadata(default(Point), VisualPropertyChanged));

        public static void VisualPropertyChanged(object sender, DependencyPropertyChangedEventArgs ea)
        {
            var instance = sender as TemplatedSelectionAdorner;
            instance.UpdateRectangle();
        }

        private void UpdateRectangle()
        {
            Rect = new Rect(Start, Finish);
            if (Finish.X > Start.X)
            {

            }
        }
    }
}
